home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Environments
/
PowerLisp 2.01
/
PowerLisp 2.01 ƒ
/
Library
/
setf.lisp
< prev
next >
Wrap
Text File
|
1996-05-20
|
5KB
|
196 lines
;;;
;;; PowerLisp 2.0
;;; Copyright © 1996 Roger Corman. All rights reserved.
;;;
;;;
;;; Common Lisp 'setf' macro.
;;;
(in-package :common-lisp)
(provide :setf)
(export '( fboundp
fdefinition
fmakunbound
print-unreadable-object
setf
defsetf))
(defun setf-function-symbol (function-specifier)
(if (consp function-specifier)
(let ((print-name (format nil "~:@(~A~)" function-specifier)))
(intern print-name
(symbol-package (cadr function-specifier))))
function-specifier))
(defmacro setf (&rest forms)
(let ((form-list nil))
(do* ((f forms (cddr f))
(place (car f) (car f))
(value (cadr f) (cadr f)))
((null f))
(if (null (cdr f)) (error "Odd number of arguments to setf: ~A" forms))
(if (symbolp place)
(setq form-list (cons `(setq ,place ,value) form-list))
(let ((expansion-func (get (car place) 'cl::_setf_expansion_)))
(if (symbolp expansion-func)
(setq form-list (cons `(,expansion-func ,value ,@(cdr place)) form-list))
(setq form-list (cons `(funcall ,expansion-func ,value ,@(cdr place)) form-list))))))
(if (cdr form-list)
`(progn ,@(nreverse form-list))
(car form-list))))
;;
;; Common Lisp 'defun' macro.
;; This redefines the built-in special form.
;;
(defmacro defun (name lambda-list &rest forms)
(let ((doc-form nil)
(lambda-form nil)
(declarations nil)
(setf-form nil))
(if (and (consp name) (eq (car name) 'setf))
(progn
(unless (symbolp (cadr name)) (error "Invalid function name: ~A" name))
(setq setf-form (cadr name))
(setq name (setf-function-symbol name))))
;; look for declarations and doc string
(do* ((f forms (cdr f)))
((null f) (setq forms f))
(if (and (typep (car f) 'string) (null doc-form) (cdr f))
(setq doc-form
`((setf (documentation ',name 'function) ,(car f))))
(if (and (consp (car f)) (eq (caar f) 'declare))
(push (car f) declarations)
(progn (setq forms f) (return)))))
(setq lambda-form
`(lambda ,lambda-list ,@(nreverse declarations)
(block ,name ,@forms)))
(if setf-form
`(progn
,@doc-form
(setf (symbol-function ',name) (function ,lambda-form))
(setf (get ',setf-form 'cl::_setf_expansion_) ',name)
',name)
`(progn
,@doc-form
(setf (symbol-function ',name) (function ,lambda-form))
',name))))
;;
;; Common Lisp 'defmacro' macro.
;; This redefines the built-in special form.
;;
(defmacro defmacro (name lambda-list &rest forms)
(let ((doc-form nil)
(lambda-form nil)
(declarations nil))
;; look for declarations and doc string
(do* ((f forms (cdr f)))
((null f) (setq forms f))
(if (and (typep (car f) 'string) (null doc-form) (cdr f))
(setq doc-form
`((setf (documentation ',name 'macro) ,(car f))))
(if (and (consp (car f)) (eq (caar f) 'declare))
(push (car f) declarations)
(progn (setq forms f) (return)))))
(setq lambda-form
`(lambda (form &optional env)
(destructuring-bind ,lambda-list
(cdr form)
,@(nreverse declarations)
(block ,name ,@forms))))
`(progn
,@doc-form
(setf (macro-function ',name) (function ,lambda-form))
',name)))
(defun apply-arg-rotate (f args)
(apply f (car (last args)) (butlast args)))
(defmacro defsetf (sym first &rest rest)
(if (symbolp first)
`(progn (cl::putprop ',sym 'cl::_setf_expansion_ ',first) ',sym)
(let ((f `#'(lambda ,(append (car rest) first) ,@(cdr rest)))
(args (gensym)))
`(progn
(setf (get ',sym 'cl::_setf_expansion_)
#'(lambda (&rest ,args) (apply-arg-rotate ,f ,args)))
',sym))))
(defun fboundp (function-specifier)
(if (consp function-specifier)
(%fboundp (get (cadr function-specifier) '_setf_expansion_))
(%fboundp function-specifier)))
(defun fdefinition (function-specifier)
(if (consp function-specifier)
(symbol-function (get (cadr function-specifier) 'cl::_setf_expansion_))
(symbol-function function-specifier)))
(defun (setf fdefinition) (value function-specifier)
(if (consp function-specifier)
(let* ((func (cadr function-specifier))
(set-sym (get func 'cl::_setf_expansion_)))
(unless set-sym
(progn
(setq set-sym (setf-function-symbol function-specifier))
(setf (get func 'cl::_setf_expansion_) set-sym)))
(setf (symbol-function set-sym) value))
(setf (symbol-function function-specifier) value)))
(defun fmakunbound (function-specifier)
(if (consp function-specifier)
(%fmakunbound (get (cadr function-specifier) 'cl::_setf_expansion_))
(%fmakunbound function-specifier)))
;;; print-unreadable-object is the standard way in the new Common Lisp
;;; to generate #< > around objects that can't be read back in. The option
;;; (:identity t) causes the inclusion of a representation of the object's
;;; identity, typically some sort of machine-dependent storage address.
(defmacro print-unreadable-object
((object stream &key type identity) &body body)
`(let ((.stream. ,stream)
(.object. ,object))
(format .stream. "#<")
,(when type
'(format .stream. "~S" (type-of .object.)))
,(when (and type (or body identity))
'(format .stream. " "))
,@body
,(when (and identity body)
'(format .stream. " "))
,(when identity
'(format .stream. "#x~X" (pl::address .object.))
)
(format .stream. ">")
nil))